/**
 * ECP Web开发 模型相关服务.
 * Copyright(c) 2012-2020 YGSoft.Inc
 * 只支持IE9 以上版本
 * author:biwei 
 * date:2014-7-21
 */
define(["ecp.service","ecp.utils","ecp.const","ecp.dmstate"],function(ecp,utils,ecpConst,dmstate){
    //数据模型
    function _dataModel_get(name){
        var result = this[name];
        if(result){
            return result;
        }
        result = this.pureModel[name];
        //如果是数组
        if($.isArray(result)){
            this[name] = result;
            for(var i=0;i<result.length;i++){
                result[i]= new DataModel(result[i]);
            }
        }else if($.isObject(result)){
            //如果是子对象
            this[name] = new DataModel(result);
        }else {
            return this.pureModel[name];
        }
    };
    function _dataModel_set(name,value){
        //处理复合对象
        if(this[name]&&(value instanceof DataModel)){
            this[name] = value;
        }else{
            this.pureModel[name]=value;
        }
    };
    function _dataModel_value(name,value){
        if(arguments.length==1){
            return this.get(name);
        }else if(arguments.length==2){
            this.set(name,value);
        }else{
            //参数错误
        }
    };
    var DataModelState = dmstate;
    //双向绑定实现
    //数据源
    var DataBindConst = {
        DATAPATH: 'ng-model',
        SINGLEDATAPATH:'ng-bind',
        DATASOURCE: 'ng-source',
        BINDPROPERTY: 'ng-attr',
        VALUEPROP: "value",
        HTMLPROP: "innerHTML",
        TEXTPROP: "innerText"
    };
    function _getCtrlBindProperty(ctrl) {
        var result = ctrl.attr(DataBindConst.BINDPROPERTY);
        if (!result) {
            result = DataBindConst.VALUEPROP;
        }
        return result;
    };
    function _onCtrlChange(e) {
        var ctrl = e.data;
        if(ctrl.attr("ecpclass") === "ecp.ui.datafield.Grid"){return;}
        //如果是调用setCtrl造成的，则返回
        if (ctrl.disableBindEvent) {
            ctrl.disableBindEvent = false;
            return;
        }
        //currentCtrlFormat格式化后又重新触发change事件，这时不应该触发，因为模型没有改变
        if (ctrl.fomartDisableEvent == true){
        	ctrl.fomartDisableEvent = false;
        	return;
        }
        //处理validateBox.若校验不通过不修改模型值
        if(ctrl.hasClass("ecp-component-validateBox")){
        	var currentVal = ctrl.val(),
    		ruleOption = $.parseJSON(ctrl.attr("data-option"));
        	if(ruleOption && ruleOption.rules && ruleOption.rules.expression){
        		var reg = new RegExp(ruleOption.rules.expression);
        		if(currentVal && !reg.test(currentVal)){
        			return;
        		}
        	}
        }
        var newValue = DataBindUtil.getCtrl(ctrl.dataCtrl);
        DataBindUtil.setModel(ctrl.dataCtrl, newValue);
    };
    function _dataSource_bind(bindCtrls) {
        if (bindCtrls) {
            if (!$.isArray(bindCtrls)) {
                bindCtrls = [bindCtrls];
            }
            var bindCtrl;
            var dsName = this.name;
            var filterStr = "*[ng-model],[ng-bind]";

            for (var bindIndex = 0; bindIndex < bindCtrls.length; bindIndex++) {
                bindCtrl = bindCtrls[bindIndex]
                //处理双向绑定
                var ctrls = bindCtrl.find(filterStr);
                if (bindCtrl.attr(DataBindConst.DATAPATH)) {
                    if (!ctrls) {
                        ctrls = [bindCtrl];
                    } else {
                        ctrls.push(bindCtrl);
                    }
                }
                if (ctrls && ctrls.length > 0) {
                    var ctrl;
                    for (var i = 0; i < ctrls.length; i++) {
                        ctrl = $(ctrls[i]);
                        //是否设置了名称匹配,名称匹配才添加，都没设也算匹配
                        var ngSource = ctrl.attr(DataBindConst.DATASOURCE);
                        if(ngSource == dsName ){
                            this.addCtrl(ctrl);    
                        }
                    }
                }
            }
            this.syncAll(true);
        }
    };
    function _dataSource_unbind(bindCtrls) {
        if (bindCtrls) {
            if (!$.isArray(bindCtrls)) {
                bindCtrls = [bindCtrls];
            }
            var bindCtrl;
            var dsName = this.name;
            var filterStr = "*[ng-model],[ng-bind]";

            for (var bindIndex = 0; bindIndex < bindCtrls.length; bindIndex++) {
                bindCtrl = bindCtrls[bindIndex]
                //处理双向绑定
                var ctrls = bindCtrl.find(filterStr);
                if (bindCtrl.attr(DataBindConst.DATAPATH)) {
                    if (!ctrls) {
                        ctrls = [bindCtrl];
                    } else {
                        ctrls.push(bindCtrl);
                    }
                }
                if (ctrls && ctrls.length > 0) {
                    var ctrl;
                    for (var i = 0; i < ctrls.length; i++) {
                        ctrl = $(ctrls[i]);
                        //是否设置了名称匹配,名称匹配才添加，都没设也算匹配
                        var ngSource = ctrl.attr(DataBindConst.DATASOURCE);
                        if(ngSource == dsName ){
                            this.removeCtrl(ctrl);    
                        }
                    }
                }
            }
        }
    };
    /**
     * 设置表格模型状态(QzzGrid).
     * @param{Array} grids 表格对象数组
     * @param{Boolean} isUpdateChange 是否只更新变更集，默认false
     */
    function _setGridModel(grids, isUpdateChange){
    	if(!grids || grids.length === 0)return;
    	var me = this, cd, model;
    	$.each(grids, function(){
    		cd = this.getEcpChangeSet();
    		if(!cd){return;}
			model = this.getControl().attr("ng-model");
			if(model){
				var gridCtrl = me.dataControls[model];
				if(!gridCtrl){return;}
				var newValue = isUpdateChange ? cd.list : this.value();
				DataModelUtil.set(gridCtrl.model, gridCtrl.modelPath, newValue, cd.deleteList, true);
			}
    	})
    }
    
    var DataControl = function (ctrl, ctrlProperty, model, modelPath) {
        this.ctrl = ctrl;
        this.ctrl.dataCtrl = this;
        this.ctrlProperty = ctrlProperty;
        this.modelPath = modelPath;
        this.model = model;
        this.dataSource = null;
        var disMD = new DisplayModel(model);
        this.displayModel = disMD.getDispayModel && disMD.getDispayModel();
    };
    /**
     * 提交数据同步处理工具方法
     * @param {Object} dataCtrl 控件的数据对象
     * @param {Boolean} mustSync 是否同步
     * @param {Boolean} dochange 执行change事件
     */
    function _syncDataCtrl(dataCtrl, mustSync, dochange) {
        if (dataCtrl) {
            var modelValue = DataBindUtil.getModel(dataCtrl);
            var sync = mustSync;
            if (!sync) {
                var modifyValue = _getModelModifyValue(dataCtrl, modelValue);
                sync = modifyValue.isModify;
            }
            if (sync) {
                DataBindUtil.setCtrl(dataCtrl, modelValue, null, dochange);
            }
        }
    }
    
    /**
     * 同步
     * @param {Boolean} mustSync 是否同步
     * @param {Boolean} dochange 执行change事件
     */
    function _postSync(props, mustSync, onchange) {
        var dataCtrls;
        for (var propIndex = 0; propIndex < props.length; propIndex++) {
            dataCtrls = this.dataControls[props[propIndex]];
            if ($.isArray(dataCtrls)) {
                var dataCtrl;
                for (var i = 0; dataCtrls && i < dataCtrls.length; i++) {
                    dataCtrl = dataCtrls[i];
                    _syncDataCtrl(dataCtrl, mustSync, onchange);
                }
            } else {
                _syncDataCtrl(dataCtrls, mustSync, onchange);
            }
        }
    };
    
    /**
     * 提交所有属性变更。
     * @param {Boolean} mustSync 是否同步
     * @param {Boolean} dochange 执行change事件
     */
    function _postSyncAll(mustSync, dochange) {
        //设置控件值
        var tmpDataCtrl;
        for (var name in this.dataControls) {
            var dataControls = this.dataControls[name];
            if ($.isArray(dataControls)) {
                for (var i = 0; i < dataControls.length; i++) {
                    tmpDataCtrl = dataControls[i];
                    _syncDataCtrl(tmpDataCtrl, mustSync, dochange);
                }
            } else {
                _syncDataCtrl(dataControls, mustSync, dochange);
            }
        }
    };
    
    function _getModelModifyValue(dataCtrl, modelValue) {
        var val;
        if (arguments.length == 2) {
            val = modelValue;
        } else {
            val = DataBindUtil.getModel(dataCtrl);
        }
        var modify = val != DataBindUtil.getCtrl(dataCtrl, true);
        return { value: val, isModify: modify };
    };
    /**
     * 增加控件的双向绑定相关属性等.
     * @param {selector} 页面元素
     */
    function _addCtrl(ctrl) {
        var ctrlProp = _getCtrlBindProperty(ctrl);
        var modelPath = ctrl.attr(DataBindConst.DATAPATH);
        var single = !modelPath;
        if(single){
            modelPath = ctrl.attr(DataBindConst.SINGLEDATAPATH);
        }else{
            ctrl.unbind("change.dataModel").bind("change.dataModel", ctrl, _onCtrlChange);
        }
        ctrl.dataSource = this;
        //设置onChange事件
        _specAddCtrl(ctrl);
        var dataControl = new DataControl(ctrl, ctrlProp, this.dataModel, modelPath);
        dataControl.dataSource = this;

        var tmpDataCtrl = this.dataControls[modelPath];
        if (tmpDataCtrl) {
            if ($.isArray(tmpDataCtrl)) {
                tmpDataCtrl.push(dataControl);
            } else {
                var ctrlList = [tmpDataCtrl, dataControl];
                this.dataControls[modelPath] = ctrlList;
            }
        } else {
            this.dataControls[modelPath] = dataControl;
        }
    };
    
    /**
     * 删除控件的双向绑定相关属性等.
     * @param {selector} 页面元素
     */
    function _removeCtrl(ctrl) {
        var ctrlProp = _getCtrlBindProperty(ctrl);
        var modelPath = ctrl.attr(DataBindConst.DATAPATH);
        var single = !modelPath;
        if(single){
            modelPath = ctrl.attr(DataBindConst.SINGLEDATAPATH);
        }else{
            ctrl.unbind("change.dataModel", ctrl, _onCtrlChange);
        }
        delete ctrl.dataSource;
        delete ctrl.dataBind;
        this.dataControls[modelPath] = null;
        delete this.dataControls[modelPath];
    };
    /**
     * 预置控件的特殊处理
     */
    function _specAddCtrl(ctrl) {
    	//处理日期
        var dataType = ctrl.attr("ng-dataType");
        if(!dataType){
        	dataType = ctrl.attr("datatype");
        }
        if( dataType && dataType.length !==0 ){
        	switch(dataType){
        		case "date": {
        			 ctrl.dataBind = {
		             	setCtrl: function (ctrl, val, onlysetCtrl,dataCtrl) {
							var oldValue =  DataModelUtil.get(dataCtrl.model, dataCtrl.modelPath);
							if(!val){
								ctrl.val("");
							}else{
								setDatePickerValue(ctrl, val);
							}
							//处理多时区，不转换format.code
							if(val != oldValue){
								ctrl.trigger("change");
							}
		             	}
        		     };
        			 break;
        		}
        		case "number": {
        			ctrl.dataBind = {
		             	setCtrl: function (ctrl, val, onlysetCtrl,dataCtrl) {
		             		if(ctrl.numberBox){
		             			var ui = ctrl.numberBox(true);
			             		if(ui && ui.value){
			             			//①百分比格式化的真实数据要乘以100
			                    	//②折合处理
			                    	var format = ui.option.format;
			                    	if(utils.notEmpty(val) && val != 0 && format && format.code){
			                    		var code = format.code,
			                    			rule = code.split("#"),
			                    			amount = ecpConst.AMOUNT[rule[4]];
			                    		if(code.indexOf("@percent") > -1){
			                    			val = val*100;
			                        	}else if(amount){
			                        		val = val/amount;
			                        	}
			                    	}
			             			ui.initValue(val);
			             		}
		             		}
		             	}
        			};
        			break;
        		}
        	}
        	return;
        }
        //处理下拉及业务组件
        var ecpclass = ctrl.attr("ecpclass");
        if(ecpclass === ecpConst.EcpClass.COMBOBOX){
        	ctrl.dataBind = {
             	setCtrl: function (ctrl, val, onlysetCtrl,dataCtrl) {
             		
             		var modelPath = dataCtrl.modelPath,
             			model = dataCtrl.model;
             		if(ctrl[0] && ctrl[0].ui){
						var ui = ctrl[0].ui;
             			if(val === undefined){
							ui.value("");
							return;
						}
             			var	opt = ui.option,
             				format = opt.format,
             				dataType = opt.transType || opt.dataType,
             				entityTypeId = opt.entityTypeId,
	             			displayModel = new DisplayModel(model, dataType, entityTypeId);
             			if(format && format.processorName){
             				//控件格式处理器，自定义格式处理
             				var modelName = ecpConst.PROCESSOR_FORMAT+format.processorName;
             				if(window._requireConfig.paths[modelName]){
             					require([modelName],function(model){
             						if(model.getValue){
             							var data = model.getValue(ctrl,val,displayModel,opt,format,modelPath,dataCtrl,model);
             							if($.isPlainObject(data)){
             								ctrl[0].ui.initValue([data]);
             							}else if($.isArray(data)){
             								ctrl[0].ui.initValue(data);
             							}else{
             								window.console.error("控件格式处理器"+modelName+"方法getValue返回值类型不对。");
             							}
             						}else{
             							window.console.error("控件格式处理器"+modelName+"不存在getValue方法。");
             						}
             					})
             				}else{
             					window.console.error("控件格式处理器"+modelName+"没有在amdconfig中找不到。");
             					return;
             				}
             			}
             			if(utils.notEmpty(displayModel)){
             				var text = displayModel.getText(val);
             				if(!text){text = "";}
             				var data = {
                     				id:val,
                     				text:text
                     			}
             				ctrl[0].ui.initValue([data]);
             			}else{
							//没有显示模型时通过id设显示值
							ctrl[0].ui.initValue(val);
						}
             		}
             	}
        	};
        	return;
        }
        //处理Select2控件设置val以后要触发事件
        var css = ctrl.attr("class");
        if (css && css.indexOf("select2") >= 0) {
            ctrl.dataBind = {
                setCtrl: function (ctrl, val, onlysetCtrl,dataCtrl) {
                    ctrl.val(val).trigger("change");
                }
            };
        }
		//处理imgPreview
        if(css && css.indexOf("ecp-component-imgPreview") >= 0){
        	 ctrl.dataBind = {
                 setCtrl: function (ctrl, val, onlysetCtrl,dataCtrl) {
                     ctrl.imgPreview('value', val);
                 }
             };
        }
        //处理validateBox控件，设置值
        if(css && css.indexOf("ecp-component-validateBox") >= 0){
       	 	ctrl.dataBind = {
                setCtrl: function (ctrl, val, onlysetCtrl,dataCtrl) {
                    if(ctrl.validateBox){
                    	var ui = ctrl.validateBox(true);
                    	ui.value(val);
                    }else{
                    	ctrl.val(val);
                    }
                }
            };
       }
       //处理枚举类型的checkBox展示控件，设置值
       if(css && css.indexOf("ecp-business-enumCheckBox") >= 0){
       	 	ctrl.dataBind = {
                setCtrl: function (ctrl, val, onlysetCtrl,dataCtrl) {
                    if(ctrl.enumCheckBox){
                    	var ui = ctrl.enumCheckBox(true);
                    	ui.value(val, dataCtrl.dataSource);
                    }
                }
            };
       }
    }
    function setDatePickerValue(ctrl, val){
		var date = "";
		if(utils.isEcpDate(val)){
			date = utils.strToDate(val);				
		}
		var dataOpt = ctrl.attr("data-option"); 
		if(dataOpt){
			dataOpt = $.parseJSON(dataOpt);
			if(dataOpt && dataOpt.format){
				date = utils.formatDatePickerValue(dataOpt.format, date);
			}
		}
		//如果是只读或不可用的日期，设置forceValue为true可强制设置值
		if(ctrl.datepicker && (!dataOpt && dataOpt && dataOpt.forceValue !== true)){
			ctrl.datepicker("setValue",date)
		}else{
			ctrl.val(date);
		}
    }
    function _findCtrls(modelPath) {
        var result = this.dataControls[modelPath];
        if ($.isArray(result)) {
            return result;
        } else {
            return [result];
        }
    };
    /**
     * 数据源对象，连接模型和控件。
     */
    var DataSource = function () {
        this.dataModel = null;
        this.dataControls = {};
        this.addCtrl = _addCtrl;
        this.removeCtrl = _removeCtrl;
        this.findCtrls = _findCtrls;
        this.bind = _dataSource_bind;
        this.unbind = _dataSource_unbind;
        this.setGridModel = _setGridModel;
        this.sync = _postSync;
        this.syncAll = _postSyncAll;
        this.onGetModel = null;//(DataBindEvent)
        this.onSetModel = null;//(DataBindEvent)
        this.onAfterSetModel = null//(DataBindEvent)
        this.onGetCtrl = null;//(DataBindEvent);
        this.onSetCtrl = null;//(DataBindEvent);
    };
    /**
     * 模型绑定事件对象.
     */
    var DataBindEvent = function () {
        this.sender = null;
        this.attr = null;
        this.value = null;
    };
    var DataBindUtil = {
        setModel: function (dataCtrl, val, onlysetValue) {
          var oldValue =  DataModelUtil.get(dataCtrl.model, dataCtrl.modelPath);
            if (!onlysetValue && dataCtrl.dataSource.onSetModel) {
                var event = { sender: dataCtrl.model, attr: dataCtrl.modelPath, value: val,oldValue :oldValue, dataCtrl: dataCtrl };
                dataCtrl.dataSource.onSetModel(event);
                val = event.value;
            }
            //日期控件值到模型时进行格式化处理
            if(val && dataCtrl.ctrl.attr("ng-datatype") == "date" && !utils.isEcpDate(val)){
        		val = utils.parseEcpDate(val);
            }
            DataModelUtil.set(dataCtrl.model, dataCtrl.modelPath, val, oldValue);
            //刷新其他绑定控件
            if (!onlysetValue) {
                var dataControls = dataCtrl.dataSource.dataControls[dataCtrl.modelPath];
                if ($.isArray(dataControls)) {
                    var tmpDataCtrl
                    for (var i = 0; i < dataControls.length; i++) {
                        tmpDataCtrl = dataControls[i];
                        if (tmpDataCtrl != dataCtrl && dataCtrl.ctrl[0] != tmpDataCtrl.ctrl[0]) {
                            DataBindUtil.setCtrl(tmpDataCtrl, DataBindUtil.getModel(tmpDataCtrl));
                        }
                    }
                } else {
                    //不是数组说明没有多个控件绑定到一个属性
                	DataBindUtil.currentCtrlFormat(dataCtrl, val);
                }
            }
            if (!onlysetValue && dataCtrl.dataSource.onAfterSetModel) {
                var event = { sender: dataCtrl.model, attr: dataCtrl.modelPath, value: val, oldValue :oldValue, dataCtrl: dataCtrl };
                dataCtrl.dataSource.onAfterSetModel(event);
            }
        },
        getModel: function (dataCtrl, onlygetValue) {
            var result = DataModelUtil.get(dataCtrl.model, dataCtrl.modelPath);
            if (!onlygetValue && dataCtrl.dataSource.onGetModel) {
                var event = { sender: dataCtrl.model, attr: dataCtrl.modelPath, value: result };
                dataCtrl.dataSource.onGetModel(event,dataCtrl);
                result = event.value;
            }
            return result;
        },
        /**
         * 当前控件进行格式化
         */
        currentCtrlFormat: function(dataCtrl, val){
        	var ctrl = dataCtrl.ctrl;
        	var dataType = ctrl.attr("ng-dataType");
        	ctrl.fomartDisableEvent = true;
            if(!dataType){
            	dataType = ctrl.attr("datatype");
            }
            if( dataType && dataType.length !==0 ){
            	switch(dataType){
            		case "date": {
		             		if(utils.isEcpDate(val)){
		             			var date = utils.strToDate(val);
		             			var dataOpt = ctrl.attr("data-option"); 
		             			if(dataOpt){
		             				dataOpt = $.parseJSON(dataOpt);
		             				if(dataOpt && dataOpt.format){
		             					date = utils.formatDatePickerValue(dataOpt.format, date);
		             				}
		             			}
	             				ctrl.val(date);
		             		}
		             		break;
        		     }
            	}
            }
            setTimeout(function(){
            	ctrl.fomartDisableEvent = false;
            },0)
        },
        setCtrl: function (dataCtrl, val, onlysetCtrl, dochange) {
            dataCtrl.ctrl.disableBindEvent = true;
            try {
                var bind = dataCtrl.ctrl.dataBind;
                if (bind && bind.setCtrl) {
                	bind.setCtrl(dataCtrl.ctrl, val, onlysetCtrl,dataCtrl);
                	if(dochange === true){
                		dataCtrl.ctrl.trigger("change");
                	}
                    return;
                }
                var prop = _getCtrlBindProperty(dataCtrl.ctrl);
                if (!onlysetCtrl && dataCtrl.dataSource.onSetCtrl) {
                    var event = { sender: dataCtrl.ctrl, attr: prop, value: val };
                    dataCtrl.dataSource.onSetCtrl(event);
                    val = event.value;
                }
                if (prop == DataBindConst.VALUEPROP) {
                	val = utils.originalAngleBrackets(val);
					var type = dataCtrl.ctrl.attr("type");
					var ctrlVal = dataCtrl.ctrl.val();
					//处理radio与checkbox情况 modi by zxw
                    if(type && utils.notEmpty(ctrlVal)){
							if(type.toLocaleLowerCase() === "radio"){
									if(ctrlVal === val){
										//dataCtrl.ctrl.val(val);
										$.uniform && $.uniform.update(dataCtrl.ctrl.attr("checked",true));
									}
							} else if(type.toLocaleLowerCase() === "checkbox"){
									var vals = (""+val).split(",");
									if($.inArray(ctrlVal,vals) != -1){
										//dataCtrl.ctrl.val(ctrlVal);
										$.uniform && $.uniform.update(dataCtrl.ctrl.attr("checked",true));
									}
							
							} else{
								dataCtrl.ctrl.val(val);
							}
                	}else{
                		dataCtrl.ctrl.val(val);
                	}
                } else if (prop == DataBindConst.HTMLPROP) {
                    dataCtrl.ctrl.html(val);
                } else if (prop == DataBindConst.TEXTPROP) {
                	val = utils.originalAngleBrackets(val);
                    dataCtrl.ctrl.text(val);
                } else {
                    dataCtrl.ctrl[0][prop] = val;
                }
                if(dochange === true){
            		dataCtrl.ctrl.trigger("change");
            	}
            } finally {
                dataCtrl.ctrl.disableBindEvent = false;
            }
        },
        getCtrl: function (dataCtrl, onlygetCtrl) {
            var bind = dataCtrl.ctrl.dataBind;
            if (bind && bind.getCtrl) {
                return bind.getCtrl(dataCtrl.ctrl, onlygetCtrl);
            }
            var prop = _getCtrlBindProperty(dataCtrl.ctrl);
            var result;
            if (prop == DataBindConst.VALUEPROP) {
            	result = dataCtrl.ctrl.val();
            } else {
                result = dataCtrl.ctrl[0][prop];
            }
            if (!onlygetCtrl && dataCtrl.dataSource.onGetCtrl) {
                var event = { sender: dataCtrl.ctrl, attr: prop, value: result };
                dataCtrl.dataSource.onGetCtrl(event);
                result = event.value;
            }
            //处理数字输入框的值为数字
            if(dataCtrl.ctrl.attr("ecpclass") === ecpConst.EcpClass.NUMBERBOX){
            	if(typeof(result) === "string"){
            		result = +result;
            	}
            	//①百分比格式化的真实数据要除以100
            	//②折合处理
            	var format = dataCtrl.ctrl.numberBox(true).option.format;
            	if(result != 0 && format && format.code){
            		var code = format.code;
            		var rule = code.split("#");
            		var amount = ecpConst.AMOUNT[rule[4]];
            		if(code.indexOf("@percent") > -1){
                		result = result/100;
                	}else if(amount){
                		result = result*amount;
                	}
            	}
            }
            result = utils.escapeAngleBrackets(result);
            if(result === ""){result = null;}
            return result;
        }
    }
    //数据模型使有包装模式，统一访问模式
    var DataModelUtil = {
        get: ecp.ObjectUtil.get,
        set: ecp.ObjectUtil.set
    }
  var DataModel = function(pureModel){
    this.pureModel=pureModel;
    if(!this.pureModel){
      this.pureModel = {};
            this.modelState = DataModelState.NEW;
        }else{
            this.modelState = pureModel['modelState'];
        };
    this.get=_dataModel_get;
    this.set=_dataModel_set;
    this.value=_dataModel_value;
    this.toJSON = function(){
        this.pureModel.modelState = this.modelState ;
        return $.toJSON(this.pureModel);
    };
  };    
  	//元数据模型使用原型模式，只扩展一些方法
    var MetaModel =  {

    };
    
    //显示模型使用原型模式，只扩展一些方法
    var DisplayModel = function(model, dataType, entityTypeId) {
    	var disMD;
    	if(model){
    		disMD = model["_displayModel"];
    		if(!disMD){
    			disMD = model["_DISPLAYMODEL"];
    		}
    	}
    	if(!utils.notEmpty(disMD) || !utils.notEmpty(dataType)){return{};}
		this.disMD = disMD;
		this.dt = dataType.toUpperCase();
    	this.dtVal = disMD[this.dt];
    	if (!this.dtVal) {
    		disMD[this.dt] = {};
    		this.dtVal = disMD[this.dt]
    	}
    	this.eIdVal = this.dtVal ? this.dtVal[entityTypeId] : null;
    	var me = this;
    	return {
    		/**
			 * 根据数据类型，引用类型，ID值，获取对应的名称.
			 * @param {String} id ID值
			 */
			getMc : function(id){
			   try{
				   	var obj = model;
					if (!obj){
						return "";
					}
					if(id == "[object Object]"){
						id = "";
					}
					//如果dt或rt为空则返回空
					var dt = me.dt,
						cIdVal = me.cIdVal;
					if( !utils.notEmpty(dt) ){
						return "";
					}
					if(!utils.notEmpty(id)){
				   		return "";
				   	}
					//将dt变成大写
					dt = dt.toUpperCase();
					if(typeof id =="string"){
						id=id.replace(/^\s+|\s+$/g,"");
						//处理管理对象dxlxid.dxid这样问题
						if(dt=="GLDX"){
						   	var p =id.indexOf(".");
						   	if(p != -1){
						   		id=id.substr(p+1);
						   	}
						}						
					}					
					var  res = "", dtVal = me.dtVal;
					if(dtVal){
						//如果dt为ENUM枚举UNITCODE单位选择控件类型则进行以下操作
						if(this.isHasReftype(dt) && utils.notEmpty(me.eIdVal) && utils.notEmpty(me.eIdVal[id])){
							res = me.eIdVal[id];
						}else{
							res = dtVal[id];
						}
					}
					if($.type(res) === "object"){
						res = res.name;
					}
					return res;
				} catch (e) {
					return "";
				}
			},
			/**
			 * 判断类型
			 * @param {String} dt dataType
			 * @returns {Boolean}
			 */
			isHasReftype:function(dt){
				return ",ENUM,DXFL,SYSENUM,UNIT,STRING,ECP.REFTYPE,ECP.TABLEENTITY,ECP.ENTITY,ECP.APP.BASE,REGION,".indexOf(","+dt+",")>-1;
			},
    		/**
    		 * 获得显示值
    		 * @param {String|Array} value id值，可以是字符串，也可以是数组
    		 */
    		getText: function(value){
    			var res="";
    			if(!utils.notEmpty(value)){return res;}
				if(typeof(value) === "number"){
					value = value + "";
				}
				if(typeof(value) === "string"){
					if(value.indexOf(",")!== -1){
    					value = value.split(",");
    				}else{
    					value = [value];
    				}
				}
				if($.type(value) === "array"){
					var val;
					for(var i=0,len=value.length; i<len; i++){
						val = this.getMc(value[i]);
						if(!val){val = "";}
						res += val + ",";
					}
					if(res){
						res = res.substring(0,res.length-1);
					}
				}
    			return res;
    		},
    		/**
    		 * 设置具体IDMC
    		 * @param {String} key id值，可以是字符串
    		 * @param {String | Object} value 对象
    		 */
    		setText: function(key, value){
    			var res="";
    			if(!utils.notEmpty(key)){return}
					var dtVal = me.dtVal;
					if(dtVal){
						var id = key;
						if(typeof id =="string"){
							id=id.replace(/^\s+|\s+$/g,"");
							//处理管理对象dxlxid.dxid这样问题
							if(me.dt=="GLDX"){
							   	var p =id.indexOf(".");
							   	if(p != -1){
							   		id=id.substr(p+1);
							   	}
							}						
						}					
						//如果dt为ENUM枚举UNITCODE单位选择控件类型则进行以下操作
						if(this.isHasReftype(me.dt) && utils.notEmpty(me.eIdVal)){
							me.eIdVal[id] = value;
						}else{
							dtVal[id] = value;
						}
				}
    		},
    		/**
    		 * 设置显示模型.
    		 */
    		setDispayModel: function(newModel){
    			disMD = newModel;
    		},
    		/**
    		 * 获得显示模型.
    		 */
    		getDisplayModel: function(){
    			return disMD;
    		}
    	}
    }
    //数据模型相关名称空间
    var model = {
        DataSource: DataSource,
        DataModel: DataModel,
        DataModelUtil: DataModelUtil,
        DataModelState: DataModelState,
        MetaModel: MetaModel,
        DisplayModel: DisplayModel
    }
    return model;
});
